#pragma once

#include <iostream>
#include <memory>
#include <functional>
#include "Connection.h"
#include "comm.h"
#include "Epoll.h"
#include "Reactor.h"

using func_t = std::function<std::string(std::string &)>;
class IOservice : public Connection
{
public:
    IOservice(int sockfd)
    {
        SetNonBlock(sockfd);
        Setsocket(sockfd);
        SetEvent(EPOLLIN | EPOLLET);
    }
    ~IOservice()
    {
    }

    virtual void Sender() override
    {
        while (1)
        {
            int n = send(Sockfd(), outbuff().c_str(), outbuff().size(), 0);
            if (n > 0)
            {
                DisCardOutString(n);
            }
            else if (n == 0)
            {
                break;
            }
            else
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    // 缓冲区写满了，下次再来
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    Excepter();
                    return;
                }
            }
        }
        if (!IsOutBufferEmpty())
        {
            Getowner()->EnableReadWrite(Sockfd(), true, true);
        }
        else
        {
            Getowner()->EnableReadWrite(Sockfd(), true, true);
        }
    }

    virtual void Recver() override
    {
        cout << "Recver: " << endl;
        while (1)
        {
            char buffer[1024];
            int n = recv(Sockfd(), buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0;
                Append(buffer);
            }
            else if (n == 0)
            {
                Excepter();
                return;
            }
            else
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    Excepter();
                    return;
                }
            }
            std::cout << "outbuffer:" << Inbuffer() << std::endl;
            std::string result;
            if (_on_message)
                result = _on_message(Inbuffer()); //
                                                  // 添加应答信息
            AppendOut(result);

            // 如何处理写的问题, outbuffer 发送给对方的问题！
            if (!IsOutBufferEmpty())
            {
                // 方案一: Sender(); // 直接发送, 推荐做法
                // 方案二: 使能Writeable即可.
                Getowner()->EnableReadWrite(Sockfd(), true, true);
            }
        }
    }
    void RegisterOnMessage(func_t on_message)
    {
        _on_message = on_message;
    }
    virtual void Excepter() override
    {
        LOG(LogLevel::INFO) << "异常结束" << Sockfd();
        Getowner()->DelConnection(Sockfd());
    }

private:
    func_t _on_message;
};